home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / m68k / dpx2.h < prev    next >
C/C++ Source or Header  |  1994-03-30  |  35KB  |  822 lines

  1. /* Definitions of target machine for GNU compiler.  
  2.    Bull DPX/2 200 and 300 systems (m68k, SysVr3).
  3.    Copyright (C) 1987, 1993, 1994 Free Software Foundation, Inc.
  4.    Contributed by Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr).
  5.  
  6. This file is part of GNU CC.
  7.  
  8. GNU CC is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2, or (at your option)
  11. any later version.
  12.  
  13. GNU CC is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with GNU CC; see the file COPYING.  If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22.  
  23. #ifndef USE_GAS
  24. #define MOTOROLA       /* Use Motorola syntax rather than "MIT" */
  25. #define SGS_NO_LI       /* Suppress jump table label usage */
  26. #define VERSADOS           /* This is the name of the assembler we have */
  27. #endif
  28.  
  29. #include "m68k/m68k.h"
  30. #undef SELECT_RTX_SECTION
  31. #include "svr3.h"
  32.  
  33. /* See m68k.h.  7 means 68020 with 68881.
  34.  * We really have 68030 and 68882,
  35.  * but this will get us going.  
  36.  */
  37. #ifndef TARGET_DEFAULT
  38. #define TARGET_DEFAULT 7
  39. #endif
  40.  
  41. #define OBJECT_FORMAT_COFF
  42. #define NO_SYS_SIGLIST
  43.  
  44. #ifdef CPP_PREDEFINES
  45. #undef CPP_PREDEFINES
  46. #endif
  47. /*
  48.  * define all the things the compiler should
  49.  */
  50. #ifdef ncl_mr
  51. # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3)  -Acpu(m68k) -Amachine(m68k)"
  52. #else
  53. # ifdef ncl_el
  54. # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3)  -Acpu(m68k) -Amachine(m68k)"
  55. # else
  56. #   define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3)  -Acpu(m68k) -Amachine(m68k)"
  57. # endif
  58. #endif
  59.  
  60. #undef    CPP_SPEC
  61. /*
  62.  * you can't get a DPX/2 without a 68882 but allow it
  63.  * to be ignored...
  64.  */
  65. # define __HAVE_68881__ 1
  66. # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }"
  67.  
  68. #define HAVE_ATEXIT
  69. #undef DO_GLOBAL_CTORS_BODY        /* don't use svr3.h version */
  70. #undef DO_GLOBAL_DTORS_BODY
  71.  
  72. #ifndef USE_GAS
  73. /*
  74.  * handle the native MOTOROLA VERSAdos assembler.
  75.  */
  76.  
  77. /* See m68k.h.  3 means 68020 with 68881 and no bitfiled
  78.  * bitfield instructions do not seem to work a clean way.
  79.  */
  80. #undef TARGET_DEFAULT
  81. #define TARGET_DEFAULT 3
  82.  
  83. /* The native assembler doesn't support fmovecr.  */
  84. #define NO_ASM_FMOVECR
  85.  
  86. #undef EXTRA_SECTIONS
  87. #undef EXTRA_SECTION_FUNCTIONS
  88. #undef READONLY_DATA_SECTION
  89. #define READONLY_DATA_SECTION data_section
  90. #undef SELECT_SECTION
  91. #undef SELECT_RTX_SECTION
  92. #define fini_section() while (0)
  93.  
  94. #undef CTORS_SECTION_ASM_OP
  95. #define CTORS_SECTION_ASM_OP "\tsection 15"
  96. #undef DTORS_SECTION_ASM_OP
  97. #define DTORS_SECTION_ASM_OP "\tsection 15"
  98. #undef INIT_SECTION_ASM_OP
  99. #define BSS_SECTION_ASM_OP     "\tsection 14"
  100. #undef TEXT_SECTION_ASM_OP
  101. #define TEXT_SECTION_ASM_OP    "\tsection 10"
  102. #undef DATA_SECTION_ASM_OP
  103. #define DATA_SECTION_ASM_OP  "\tsection 15"
  104.  
  105.  
  106. /* Don't try using XFmode.  */
  107. #undef LONG_DOUBLE_TYPE_SIZE
  108. #define LONG_DOUBLE_TYPE_SIZE 64
  109.  
  110. /* Define if you don't want extended real, but do want to use the
  111.    software floating point emulator for REAL_ARITHMETIC and
  112.    decimal <-> binary conversion. */
  113. #define REAL_ARITHMETIC 
  114.  
  115. #undef ASM_OUTPUT_SOURCE_FILENAME
  116. #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA)    \
  117.   do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0)
  118.  
  119. /* Assembler pseudos to introduce constants of various size.  */
  120.  
  121. #undef ASM_BYTE_OP
  122. #define ASM_BYTE_OP "\tdc.b"
  123. #undef ASM_LONG
  124. #define ASM_LONG "\tdc.l"
  125.  
  126. /* 
  127.  * we don't seem to support any of:
  128.  * .globl
  129.  * .even
  130.  * .align
  131.  * .ascii
  132.  */
  133. #undef ASM_OUTPUT_SKIP
  134. #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
  135.   fprintf (FILE, "\tdcb.b %u,0\n", (SIZE))
  136.  
  137. #undef GLOBAL_ASM_OP 
  138. #define GLOBAL_ASM_OP "\txdef"
  139.  
  140. #undef ASM_OUTPUT_ALIGN
  141. #define ASM_OUTPUT_ALIGN(FILE,LOG)    \
  142.   if ((LOG) >= 1)            \
  143.     fprintf (FILE, "\tds.w 0\n");
  144.  
  145.  
  146. #define STRING_LIMIT    (0)
  147. #undef ASM_APP_ON
  148. #define ASM_APP_ON ""
  149. #undef ASM_APP_OFF
  150. #define ASM_APP_OFF ""
  151. /*
  152.  * dc.b 'hello, world!'
  153.  * dc.b 10,0
  154.  * is how we have to output "hello, world!\n"
  155.  */
  156. #undef ASM_OUTPUT_ASCII
  157. #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize)        \
  158.   do { register int i, c, f=0, len=0;                \
  159.   for (i = 0; i < thissize; i++) {                 \
  160.     c = p[i];                            \
  161.     if (c == '\'' || c < ' ' || c > 127) {            \
  162.       switch(f) {                        \
  163.       case 0: /* need to output dc.b etc */            \
  164.     fprintf(asm_out_file, "\tdc.b %d", c);            \
  165.     f=1;                            \
  166.     break;                            \
  167.       case 1:                            \
  168.     fprintf(asm_out_file, ",%d", c);            \
  169.     break;                            \
  170.       default:                            \
  171.     /* close a string */                    \
  172.     fprintf(asm_out_file, "'\n\tdc.b %d", c);        \
  173.     f=1;                            \
  174.     break;                            \
  175.       }                                \
  176.     } else {                            \
  177.       switch(f) {                        \
  178.       case 0:                            \
  179.     fprintf(asm_out_file, "\tdc.b '%c", c);            \
  180.     f=2;                            \
  181.     break;                            \
  182.       case 2:                            \
  183.         if (len >= 79) {                    \
  184.           fprintf(asm_out_file, "'\n\tdc.b '%c", c);             \
  185.           len = 0; }                        \
  186.         else                            \
  187.       fprintf(asm_out_file, "%c", c);            \
  188.     break;                            \
  189.       default:                            \
  190.     len = 0;                        \
  191.     fprintf(asm_out_file, "\n\tdc.b '%c", c);        \
  192.     f=2;                            \
  193.     break;                            \
  194.       }                                \
  195.     }                                \
  196.     len++;                                               \
  197.   }                                \
  198.   if (f==2)                            \
  199.     putc('\'', asm_out_file);                    \
  200.   putc('\n', asm_out_file); } while (0)
  201.  
  202. /* This is how to output an insn to push a register on the stack.
  203.    It need not be very fast code.  */
  204.  
  205. #undef ASM_OUTPUT_REG_PUSH
  206. #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
  207.   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
  208.  
  209. /* This is how to output an insn to pop a register from the stack.
  210.    It need not be very fast code.  */
  211.  
  212. #undef ASM_OUTPUT_REG_POP
  213. #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
  214.   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
  215.  
  216.  
  217. #define PUT_SDB_FUNCTION_START(LINE)        \
  218.   fprintf (asm_out_file,            \
  219.        "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
  220.        SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
  221.  
  222. #define PUT_SDB_FUNCTION_END(LINE)        \
  223.   fprintf (asm_out_file,            \
  224.        "\t.def\t.ef%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
  225.        SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
  226.  
  227. #define PUT_SDB_BLOCK_START(LINE)        \
  228.   fprintf (asm_out_file,            \
  229.        "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
  230.        SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
  231.  
  232. #define PUT_SDB_BLOCK_END(LINE)            \
  233.   fprintf (asm_out_file,            \
  234.        "\t.def\t.eb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n",  \
  235.        SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
  236.  
  237. #define PUT_SDB_EPILOGUE_END(NAME)    
  238.  
  239. /* Output type in decimal not in octal as done in sdbout.c */    
  240. #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM)
  241.         
  242. #undef FUNCTION_PROLOGUE
  243. #define FUNCTION_PROLOGUE(FILE, SIZE)                                 \
  244. {                                                                     \
  245.   register int regno;                                                 \
  246.   register int mask = 0;                                              \
  247.   int num_saved_regs = 0, first = 1;                                  \
  248.   extern char call_used_regs[];                                       \
  249.   int fsize = ((SIZE) + 3) & -4;                                      \
  250.                                                                       \
  251.                                                                       \
  252.   if (frame_pointer_needed)                                           \
  253.     {                                                                 \
  254.       /* Adding negative number is faster on the 68040.  */           \
  255.       if (fsize < 0x8000 && !TARGET_68040)                            \
  256.     {                                                             \
  257.       fprintf (FILE, "\tlink %s,#%d\n",                           \
  258.                reg_names[FRAME_POINTER_REGNUM], -fsize);      \
  259.     }                                                             \
  260.       else if (TARGET_68020)                                          \
  261.     {                                                             \
  262.       fprintf (FILE, "\tlink %s,#%d\n",                          \
  263.                reg_names[FRAME_POINTER_REGNUM], -fsize);      \
  264.     }                                                             \
  265.       else                                                            \
  266.     {                                                             \
  267.       fprintf (FILE, "\tlink %s,#0\n\tadd.l #%d,sp\n",          \
  268.                reg_names[FRAME_POINTER_REGNUM], -fsize);      \
  269.     }                                  \
  270.     }                                      \
  271.   else if (fsize)                              \
  272.     {                                      \
  273.       /* Adding negative number is faster on the 68040.  */          \
  274.       if (fsize + 4 < 0x8000)                          \
  275.     {                                  \
  276.       fprintf (FILE, "\tadd.w #%d,sp\n", - (fsize + 4));          \
  277.     }                                  \
  278.       else                                  \
  279.     {                                  \
  280.       fprintf (FILE, "\tadd.l #%d,sp\n", - (fsize + 4));          \
  281.     }                                  \
  282.     }                                      \
  283.   for (regno = 23; regno >= 16; regno--)                              \
  284.     if (regs_ever_live[regno] && ! call_used_regs[regno])             \
  285.       if (first) {                              \
  286.         fprintf (FILE, "\tfmovem.x %s", reg_names[regno]);            \
  287.     first = 0;                              \
  288.        }                                  \
  289.       else fprintf (FILE, "/%s", reg_names[regno]);                      \
  290.   if (!first) fprintf (FILE, ",-(sp)\n");                  \
  291.                                       \
  292.   mask = 0;                                  \
  293.   for (regno = 0; regno < 16; regno++)                      \
  294.     if (regs_ever_live[regno] && ! call_used_regs[regno])          \
  295.       {                                      \
  296.         mask |= 1 << (15 - regno);                      \
  297.         num_saved_regs++;                                     \
  298.       }                                                               \
  299.   if (frame_pointer_needed)                                           \
  300.     {                                                                 \
  301.       mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));                   \
  302.       num_saved_regs--;                                               \
  303.     }                                                                 \
  304.                                                                       \
  305.                                                                       \
  306.   if (num_saved_regs <= 2)                                            \
  307.     {                                                                 \
  308.       /* Store each separately in the same order moveml uses.         \
  309.          Using two movel instructions instead of a single moveml      \
  310.          is about 15% faster for the 68020 and 68030 at no expense    \
  311.          in code size */                                              \
  312.                                                                       \
  313.       int i;                                                          \
  314.                                                                       \
  315.       /* Undo the work from above. */                                 \
  316.       for (i = 0; i< 16; i++)                                         \
  317.         if (mask & (1 << i))                                          \
  318.           fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - i]);   \
  319.     }                                                                 \
  320.   else if (mask)                                                      \
  321.     {                                                                 \
  322.       first = 1;                                                      \
  323.       for (regno = 0; regno < 16; regno++)                            \
  324.         if (mask & (1 << regno))                                      \
  325.           if (first) {                                                \
  326.             fprintf (FILE, "\tmovem.l %s", reg_names[15 - regno]);    \
  327.             first = 0;                                                \
  328.            }                                                          \
  329.           else fprintf (FILE, "/%s", reg_names[15 - regno]);          \
  330.       fprintf (FILE, ",-(sp)\n");                             \
  331.     }                                                                 \
  332.   if (flag_pic && current_function_uses_pic_offset_table)             \
  333.     {                                                                 \
  334.       fprintf (FILE, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n",        \
  335.            reg_names[PIC_OFFSET_TABLE_REGNUM]);               \
  336.       fprintf (FILE, "\tlea.l (pc,%s.l),%s\n",                        \
  337.            reg_names[PIC_OFFSET_TABLE_REGNUM],                \
  338.            reg_names[PIC_OFFSET_TABLE_REGNUM]);               \
  339.     }                                                                 \
  340. }
  341.  
  342.  
  343. #undef FUNCTION_EPILOGUE
  344. #define FUNCTION_EPILOGUE(FILE, SIZE)                                 \
  345. {                                                                     \
  346.   register int regno;                                                 \
  347.   register int mask, fmask;                                           \
  348.   register int nregs;                                                 \
  349.   int offset, foffset, fpoffset, first = 1;                      \
  350.   extern char call_used_regs[];                                       \
  351.   int fsize = ((SIZE) + 3) & -4;                                      \
  352.   int big = 0;                                                        \
  353.   rtx insn = get_last_insn ();                                        \
  354.                                                                       \
  355.   /* If the last insn was a BARRIER, we don't have to write any code.  */ \
  356.   if (GET_CODE (insn) == NOTE)                                        \
  357.     insn = prev_nonnote_insn (insn);                                  \
  358.   if (insn && GET_CODE (insn) == BARRIER)                             \
  359.     {                                                                 \
  360.       /* Output just a no-op so that debuggers don't get confused     \
  361.      about which function the pc is in at this address.  */       \
  362.       fprintf (FILE, "\tnop\n");                                      \
  363.       return;                                                         \
  364.     }                                                                 \
  365.                                                                       \
  366.   nregs = 0;  fmask = 0; fpoffset = 0;                                \
  367.   for (regno = 16; regno < 24; regno++)                               \
  368.     if (regs_ever_live[regno] && ! call_used_regs[regno])             \
  369.       {                                                               \
  370.         nregs++;                                                      \
  371.     fmask |= 1 << (23 - regno);                                   \
  372.       }                                                               \
  373.   foffset = fpoffset + nregs * 12;                                    \
  374.   nregs = 0;  mask = 0;                                               \
  375.   if (frame_pointer_needed)                                           \
  376.     regs_ever_live[FRAME_POINTER_REGNUM] = 0;                         \
  377.   for (regno = 0; regno < 16; regno++)                                \
  378.     if (regs_ever_live[regno] && ! call_used_regs[regno])             \
  379.       {                                                               \
  380.         nregs++;                                                      \
  381.     mask |= 1 << regno;                                           \
  382.       }                                                               \
  383.   offset = foffset + nregs * 4;                                       \
  384.   if (offset + fsize >= 0x8000                                        \
  385.       && frame_pointer_needed                                         \
  386.       && (mask || fmask || fpoffset))                                 \
  387.     {                                                                 \
  388.       fprintf (FILE, "\tmove.l #%d,a0\n", -fsize);                    \
  389.       fsize = 0, big = 1;                                             \
  390.     }                                                                 \
  391.   if (nregs <= 2)                                                     \
  392.     {                                                                 \
  393.       /* Restore each separately in the same order moveml does.       \
  394.          Using two movel instructions instead of a single moveml      \
  395.          is about 15% faster for the 68020 and 68030 at no expense    \
  396.          in code size. */                                             \
  397.                                                                       \
  398.       int i;                                                          \
  399.                                                                       \
  400.       /* Undo the work from above. */                                 \
  401.       for (i = 0; i< 16; i++)                                         \
  402.         if (mask & (1 << i))                                          \
  403.           {                                                           \
  404.             if (big)                                                  \
  405.           {                                                       \
  406.         fprintf (FILE, "\tmove.l -%d(%s,a0.l),%s\n",          \
  407.                  offset + fsize,                          \
  408.                  reg_names[FRAME_POINTER_REGNUM],         \
  409.                  reg_names[i]);                           \
  410.           }                                                       \
  411.             else if (! frame_pointer_needed)                          \
  412.           {                                                       \
  413.         fprintf (FILE, "\tmove.l (sp)+,%s\n",                 \
  414.                  reg_names[i]);                           \
  415.           }                                                       \
  416.             else                                                      \
  417.           {                                                       \
  418.         fprintf (FILE, "\tmove.l -%d(%s),%s\n",               \
  419.                  offset + fsize,                          \
  420.                  reg_names[FRAME_POINTER_REGNUM],         \
  421.                  reg_names[i]);                           \
  422.           }                                                       \
  423.             offset = offset - 4;                                      \
  424.           }                                                           \
  425.     }                                                                 \
  426.   else if (mask)                                                      \
  427.     {                                                                 \
  428.       first = 1;                              \
  429.       for (regno = 0; regno < 16; regno++)                            \
  430.         if (mask & (1 << regno))                                      \
  431.           if (first && big) {                                         \
  432.             fprintf (FILE, "\tmovem.l -%d(%s,a0.l),%s",               \
  433.              offset + fsize,                                  \
  434.              reg_names[FRAME_POINTER_REGNUM],                 \
  435.              reg_names[regno]);                               \
  436.             first = 0;                                                \
  437.            }                                                          \
  438.           else if (first && ! frame_pointer_needed) {                 \
  439.             fprintf (FILE, "\tmovem.l (sp)+,%s",                      \
  440.              offset + fsize,                                  \
  441.              reg_names[FRAME_POINTER_REGNUM],                 \
  442.              reg_names[regno]);                               \
  443.             first = 0;                                                \
  444.            }                                                          \
  445.           else if (first) {                                 \
  446.             fprintf (FILE, "\tmovem.l -%d(%s),%s",                    \
  447.              offset + fsize,                                  \
  448.              reg_names[FRAME_POINTER_REGNUM],                 \
  449.              reg_names[regno]);                               \
  450.             first = 0;                                                \
  451.            }                                                          \
  452.           else                                \
  453.         fprintf (FILE, "/%s", reg_names[regno]);                  \
  454.       fprintf (FILE, "\n");                                   \
  455.     }                                                                 \
  456.   if (fmask)                                                          \
  457.     {                                                                 \
  458.       first = 1;                              \
  459.       for (regno = 16; regno < 24; regno++)                           \
  460.         if (fmask & (1 << (23 - regno)))                               \
  461.           if (first && big) {                                          \
  462.             fprintf (FILE, "\tfmovem.x -%d(%s,a0.l),%s",              \
  463.              foffset + fsize,                                 \
  464.              reg_names[FRAME_POINTER_REGNUM],                 \
  465.              reg_names[regno]);                               \
  466.         first = 0;                              \
  467.            }                                                          \
  468.           else if (first && ! frame_pointer_needed) {                 \
  469.             fprintf (FILE, "\tfmovem.x (sp)+,%s",                     \
  470.              foffset + fsize,                                 \
  471.              reg_names[FRAME_POINTER_REGNUM],                 \
  472.              reg_names[regno]);                               \
  473.         first = 0;                              \
  474.            }                                                          \
  475.           else if (first) {                                  \
  476.             fprintf (FILE, "\tfmovem.x -%d(%s),%s",                   \
  477.              foffset + fsize,                                 \
  478.              reg_names[FRAME_POINTER_REGNUM],                 \
  479.              reg_names[regno]);                               \
  480.         first = 0;                              \
  481.            }                                                          \
  482.       else fprintf (FILE, "/%s", reg_names[regno]);           \
  483.       fprintf (FILE, "\n");                          \
  484.     }                                                                 \
  485.   if (frame_pointer_needed)                                           \
  486.     fprintf (FILE, "\tunlk %s\n",                                     \
  487.          reg_names[FRAME_POINTER_REGNUM]);                        \
  488.   else if (fsize)                                                     \
  489.     {                                                                 \
  490.       if (fsize + 4 < 0x8000)                                         \
  491.     {                                                             \
  492.       fprintf (FILE, "\tadd.w #%d,sp\n", fsize + 4);              \
  493.     }                                                             \
  494.       else                                                            \
  495.     {                                                             \
  496.       fprintf (FILE, "\tadd.l #%d,sp\n", fsize + 4);              \
  497.     }                                                             \
  498.     }                                                                 \
  499.   if (current_function_pops_args)                                     \
  500.     fprintf (FILE, "\trtd #%d\n", current_function_pops_args);        \
  501.   else                                                                \
  502.     fprintf (FILE, "\trts\n");                                        \
  503. }
  504.  
  505. /* Translate Motorola opcodes such as `jbeq'
  506.    into VERSAdos opcodes such as `beq'.
  507.    Change `fbeq' to `fbseq', `fbne' to `fbsneq'.
  508. */
  509.  
  510. #undef ASM_OUTPUT_OPCODE
  511. #define ASM_OUTPUT_OPCODE(FILE, PTR)            \
  512. { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')        \
  513.     { ++(PTR);                        \
  514.       while (*(PTR) != ' ')                \
  515.     { putc (*(PTR), (FILE)); ++(PTR); }        \
  516.     }                                          \
  517.   else if ((PTR)[0] == 'f')                             \
  518.     {                                                   \
  519.       if (!strncmp ((PTR), "fbeq", 4))                  \
  520.         { fprintf ((FILE), "fbseq"); (PTR) += 4; }      \
  521.       else if (!strncmp ((PTR), "fbne", 4))             \
  522.         { fprintf ((FILE), "fbsneq"); (PTR) += 4; }     \
  523.     }                                                   \
  524.   else if ((PTR)[0] == 'b' && (PTR)[1] == 'f')          \
  525.     {                                                   \
  526.       char *s;                                          \
  527.       if ((s = (char*)strchr ((PTR), '{')))             \
  528.     while (*s != '}') {                             \
  529.       if (*s == 'b')                                \
  530.         /* hack, I replace it with R ie nothing */  \
  531.         *s = '0';                                   \
  532.       s++; }                    \
  533.     }                                                   \
  534. }
  535.  
  536. /* This is how to output a `long double' extended real constant. */
  537. #undef ASM_OUTPUT_LONG_DOUBLE 
  538. #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)                  \
  539. do { long l[3];                                \
  540.      REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l);            \
  541.      if (sizeof (int) == sizeof (long))                    \
  542.        fprintf (FILE, "\tdc.l $%x,$%x,$%x\n", l[0], l[1], l[2]);    \
  543.      else                                \
  544.        fprintf (FILE, "\tdc.l $%lx,$%lx,$%lx\n", l[0], l[1], l[2]);    \
  545.    } while (0)
  546.  
  547. #undef ASM_OUTPUT_DOUBLE
  548. #if 0
  549. #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
  550.   do { char dstr[30];                        \
  551.        REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);        \
  552.        fprintf (FILE, "\tdc.d %s\n", dstr);                \
  553.      } while (0)
  554. #endif
  555. #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
  556. do { long l[2];                                \
  557.      REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);                    \
  558.      fprintf (FILE, "\tdc.l $%x,$%x\n", l[0], l[1]);                \
  559.    } while (0)
  560.  
  561.  
  562. /* This is how to output an assembler line defining a `float' constant.  */
  563. #undef ASM_OUTPUT_FLOAT
  564. #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
  565. do { long l;                        \
  566.      REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);        \
  567.      if (sizeof (int) == sizeof (long))            \
  568.        fprintf (FILE, "\tdc.l $%x\n", l);        \
  569.      else                        \
  570.        fprintf (FILE, "\tdc.l $%lx\n", l);        \
  571.    } while (0)
  572.  
  573. /* This is how to output an assembler line defining an `int' constant.  */
  574. #undef ASM_OUTPUT_INT 
  575. #define ASM_OUTPUT_INT(FILE,VALUE)  \
  576. ( fprintf (FILE, "\tdc.l "),            \
  577.   output_addr_const (FILE, (VALUE)),        \
  578.   fprintf (FILE, "\n"))
  579.  
  580. /* Likewise for `char' and `short' constants.  */
  581. #undef ASM_OUTPUT_SHORT
  582. #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
  583. ( fprintf (FILE, "\tdc.w "),            \
  584.   output_addr_const (FILE, (VALUE)),        \
  585.   fprintf (FILE, "\n"))
  586.  
  587. #undef ASM_OUTPUT_CHAR
  588. #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
  589. ( fprintf (FILE, "\tdc.b "),            \
  590.   output_addr_const (FILE, (VALUE)),        \
  591.   fprintf (FILE, "\n"))
  592.  
  593. /* This is how to output an assembler line for a numeric constant byte.  */
  594. #undef ASM_OUTPUT_BYTE
  595. #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
  596.   fprintf (FILE, "\tdc.b $%x\n", (VALUE))
  597.  
  598. /* This is how to output an element of a case-vector that is absolute.
  599.    (The 68000 does not use such vectors,
  600.    but we must define this macro anyway.)  */
  601. #undef ASM_OUTPUT_ADDR_VEC_ELT
  602. #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
  603.   asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
  604.  
  605. /* This is how to output an element of a case-vector that is relative.  */
  606. #undef ASM_OUTPUT_ADDR_DIFF_ELT
  607. #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
  608.   asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
  609.  
  610. /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
  611.    keep switch tables in the text section. */
  612. #define JUMP_TABLES_IN_TEXT_SECTION 1
  613.  
  614. /* Output a float value (represented as a C double) as an immediate operand.
  615.    This macro is a 68k-specific macro.  */
  616. #undef ASM_OUTPUT_FLOAT_OPERAND
  617. #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)        \
  618.  do {                                \
  619.       if (CODE == 'f')                        \
  620.         {                            \
  621.           char dstr[30];                    \
  622.           REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);        \
  623.           asm_fprintf ((FILE), "%I%s", dstr);            \
  624.         }                            \
  625.       else                            \
  626.         {                            \
  627.           long l;                        \
  628.           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);        \
  629.           if (sizeof (int) == sizeof (long))            \
  630.             asm_fprintf ((FILE), "%I$%x", l);            \
  631.           else                            \
  632.             asm_fprintf ((FILE), "%I$%lx", l);            \
  633.         }                            \
  634.      } while (0)
  635.  
  636. /* Output a double value (represented as a C double) as an immediate operand.
  637.    This macro is a 68k-specific macro.  */
  638. #undef ASM_OUTPUT_DOUBLE_OPERAND 
  639. #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                \
  640.  do { char dstr[30];                            \
  641.       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);            \
  642.       asm_fprintf (FILE, "%I%s", dstr);                    \
  643.     } while (0)
  644.  
  645. /* Note, long double immediate operands are not actually
  646.    generated by m68k.md.  */
  647. #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
  648. #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)            \
  649.  do { char dstr[30];                            \
  650.       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);            \
  651.       asm_fprintf (FILE, "%I%s", dstr);                    \
  652.     } while (0)
  653.  
  654. #undef ASM_OUTPUT_COMMON
  655. #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
  656. ( fputs ("\t.comm ", (FILE)),            \
  657.   assemble_name ((FILE), (NAME)),        \
  658.   fprintf ((FILE), ",%u\n", (ROUNDED)))
  659.  
  660. #undef ASM_OUTPUT_LOCAL
  661. #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)    \
  662.   do {                            \
  663.     int align = exact_log2 (ROUNDED);            \
  664.     /*fprintf ((FILE), "\tsection 14\n");  */               \
  665.     data_section ();                    \
  666.     ASM_OUTPUT_ALIGN ((FILE), align)                    \
  667.     ASM_OUTPUT_LABEL ((FILE), (NAME));            \
  668.     fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED));    \
  669.     /* fprintf ((FILE), "\tsection 10\n"); */             \
  670.   } while (0)
  671.  
  672. #undef PRINT_OPERAND_ADDRESS
  673. #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
  674. { register rtx reg1, reg2, breg, ireg;                    \
  675.   register rtx addr = ADDR;                        \
  676.   rtx offset;                                \
  677.   switch (GET_CODE (addr))                        \
  678.     {                                    \
  679.     case REG:                                \
  680.       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);            \
  681.       break;                                \
  682.     case PRE_DEC:                            \
  683.       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);    \
  684.       break;                                \
  685.     case POST_INC:                            \
  686.       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);    \
  687.       break;                                \
  688.     case PLUS:                                \
  689.       reg1 = 0;    reg2 = 0;                        \
  690.       ireg = 0;    breg = 0;                        \
  691.       offset = 0;                            \
  692.       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                \
  693.     {                                \
  694.       offset = XEXP (addr, 0);                    \
  695.       addr = XEXP (addr, 1);                    \
  696.     }                                \
  697.       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))            \
  698.     {                                \
  699.       offset = XEXP (addr, 1);                    \
  700.       addr = XEXP (addr, 0);                    \
  701.     }                                \
  702.       if (GET_CODE (addr) != PLUS) ;                    \
  703.       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)        \
  704.     {                                \
  705.       reg1 = XEXP (addr, 0);                    \
  706.       addr = XEXP (addr, 1);                    \
  707.     }                                \
  708.       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)        \
  709.     {                                \
  710.       reg1 = XEXP (addr, 1);                    \
  711.       addr = XEXP (addr, 0);                    \
  712.     }                                \
  713.       else if (GET_CODE (XEXP (addr, 0)) == MULT)            \
  714.     {                                \
  715.       reg1 = XEXP (addr, 0);                    \
  716.       addr = XEXP (addr, 1);                    \
  717.     }                                \
  718.       else if (GET_CODE (XEXP (addr, 1)) == MULT)            \
  719.     {                                \
  720.       reg1 = XEXP (addr, 1);                    \
  721.       addr = XEXP (addr, 0);                    \
  722.     }                                \
  723.       else if (GET_CODE (XEXP (addr, 0)) == REG)            \
  724.     {                                \
  725.       reg1 = XEXP (addr, 0);                    \
  726.       addr = XEXP (addr, 1);                    \
  727.     }                                \
  728.       else if (GET_CODE (XEXP (addr, 1)) == REG)            \
  729.     {                                \
  730.       reg1 = XEXP (addr, 1);                    \
  731.       addr = XEXP (addr, 0);                    \
  732.     }                                \
  733.       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT        \
  734.       || GET_CODE (addr) == SIGN_EXTEND)                \
  735.     { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }    \
  736. /*  for OLD_INDEXING                            \
  737.       else if (GET_CODE (addr) == PLUS)                    \
  738.     {                                \
  739.       if (GET_CODE (XEXP (addr, 0)) == REG)                \
  740.         {                                \
  741.           reg2 = XEXP (addr, 0);                    \
  742.           addr = XEXP (addr, 1);                    \
  743.         }                                \
  744.       else if (GET_CODE (XEXP (addr, 1)) == REG)            \
  745.         {                                \
  746.           reg2 = XEXP (addr, 1);                    \
  747.           addr = XEXP (addr, 0);                    \
  748.         }                                \
  749.     }                                \
  750.   */                                    \
  751.       if (offset != 0) { if (addr != 0) abort (); addr = offset; }    \
  752.       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND            \
  753.             || GET_CODE (reg1) == MULT))            \
  754.       || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))        \
  755.     { breg = reg2; ireg = reg1; }                    \
  756.       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))        \
  757.     { breg = reg1; ireg = reg2; }                    \
  758.       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)    \
  759.         { int scale = 1;                        \
  760.       if (GET_CODE (ireg) == MULT)                    \
  761.         { scale = INTVAL (XEXP (ireg, 1));                \
  762.           ireg = XEXP (ireg, 0); }                    \
  763.       if (GET_CODE (ireg) == SIGN_EXTEND)                \
  764.         fprintf (FILE, "(.L%d,pc,%s.w",                \
  765.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  766.              reg_names[REGNO (XEXP (ireg, 0))]);         \
  767.       else                                \
  768.         fprintf (FILE, "(.L%d,pc,%s.l",                \
  769.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  770.              reg_names[REGNO (ireg)]);                \
  771.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  772.       putc (')', FILE);                        \
  773.       break; }                            \
  774.     if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF      \
  775.         && ! (flag_pic && breg == pic_offset_table_rtx))            \
  776.       {                                                             \
  777.         fprintf (FILE, "(.L%d,pc,%s.l",                             \
  778.              CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  779.              reg_names[REGNO (breg)]);                      \
  780.         putc (')', FILE);                                           \
  781.         break; }                                                    \
  782.       if (ireg != 0 || breg != 0)                    \
  783.     { int scale = 1;                        \
  784.       if (breg == 0)                        \
  785.         abort ();                            \
  786.           putc ('(', FILE);                                  \
  787.       if (addr != 0)                        \
  788.         {                                                           \
  789.           output_addr_const (FILE, addr);                \
  790.           putc (',', FILE);                     \
  791.         }                                \
  792.       fprintf (FILE, "%s", reg_names[REGNO (breg)]);        \
  793.       if (ireg != 0)                        \
  794.         putc (',', FILE);                        \
  795.       if (ireg != 0 && GET_CODE (ireg) == MULT)            \
  796.         { scale = INTVAL (XEXP (ireg, 1));                \
  797.           ireg = XEXP (ireg, 0); }                    \
  798.       if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)        \
  799.         fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);    \
  800.       else if (ireg != 0)                        \
  801.         fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);        \
  802.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  803.       putc (')', FILE);                        \
  804.       break;                            \
  805.     }                                \
  806.       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)        \
  807.     { fprintf (FILE, "(.L%d,pc,%s.w)",                \
  808.            CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  809.            reg_names[REGNO (reg1)]);                \
  810.       break; }                            \
  811.     default:                                \
  812.       if (GET_CODE (addr) == CONST_INT                    \
  813.       && INTVAL (addr) < 0x8000                    \
  814.       && INTVAL (addr) >= -0x8000)                    \
  815.     fprintf (FILE, "%d.w", INTVAL (addr));                \
  816.       else                                \
  817.         output_addr_const (FILE, addr);                    \
  818.     }}
  819.  
  820.  
  821. #endif /* ! use gas */            
  822.